#include "utils/socket.h"
#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>

using namespace cox;

void testMultiPortServer() {
	// 1. 创建并初始化多个TCP服务器套接字（监听8001和8002端口）
	std::vector<std::unique_ptr<Socket>> serverSockets;
	std::vector<unsigned short>          ports = {8001, 8002}; // 要监听的端口列表

	for (auto port: ports) {
		std::unique_ptr<Socket> serverSocket(new Socket(Socket::TCP));
		if (!serverSocket->isValid()) {
			std::cerr << "创建服务器Socket（端口" << port << "）失败，错误码：" << serverSocket->getError() << std::endl;
			return;
		}

		// 设置地址复用（避免端口占用问题）
		if (!serverSocket->setReuseAddr(true)) {
			std::cerr << "端口" << port << "设置地址复用失败" << std::endl;
			return;
		}

		// 绑定地址
		NetAddr serverAddr("0.0.0.0", port);
		if (!serverSocket->bind(serverAddr)) {
			std::cerr << "端口" << port << "绑定失败，错误码：" << serverSocket->getError() << std::endl;
			return;
		}

		// 开始监听
		if (!serverSocket->listen(10)) {
			std::cerr << "端口" << port << "监听失败，错误码：" << serverSocket->getError() << std::endl;
			return;
		}

		std::cout << "TCP服务器启动，监听 " << serverAddr.host << ":" << serverAddr.port << std::endl;
		serverSockets.push_back(std::move(serverSocket));
	}

	// 2. 管理客户端连接（智能指针自动释放）
	std::vector<std::unique_ptr<Socket>> clientSockets;

	// 3. select事件循环
	while (true) {
		// 构建待监控的可读套接字列表
		std::vector<Socket *> readVec;

		// 添加所有服务器套接字（监控新连接）
		for (const auto &server: serverSockets) {
			readVec.push_back(server.get());
		}

		// 添加所有客户端套接字（监控数据）
		for (const auto &client: clientSockets) {
			readVec.push_back(client.get());
		}

		// 等待可读事件（超时1秒）
		int ret = Socket::select(&readVec, nullptr, nullptr, TimeVal(1, 0));
		if (ret < 0) {
			std::cerr << "select错误" << std::endl;
			break;
		} else if (ret == 0) {
			continue; // 超时，继续循环
		}

		// 处理就绪的套接字
		for (Socket *sock: readVec) {
			// 判断是否是服务器套接字（处理新连接）
			bool isServer = false;
			for (const auto &server: serverSockets) {
				if (sock == server.get()) {
					isServer = true;
					// 接受新连接
					auto clientSocket = server->accept();
					if (clientSocket) {
						NetAddr clientAddr = clientSocket->getAddr();
						std::cout << "新客户端连接（来自端口" << server->getAddr().port << "）：" << clientAddr.host << ":" << clientAddr.port << std::endl;

						// 发送欢迎消息
						const char *msg = "欢迎连接多端口TCP服务器！";
						clientSocket->send(msg, strlen(msg));

						// 将新客户端加入监控列表
						clientSockets.push_back(std::move(clientSocket));
					}
					break;
				}
			}

			// 如果是客户端套接字（处理数据）
			if (!isServer) {
				char      buf[1024] = {0};
				long long recvLen   = sock->recv(buf, 1023);
				if (recvLen > 0) {
					std::cout << "收到客户端（" << sock->getAddr().host << ":" << sock->getAddr().port << "）数据：" << buf << std::endl;
					// 回声回复
					sock->send(buf, recvLen);
				} else {
					// 连接断开，移除客户端
					std::cout << "客户端（" << sock->getAddr().host << ":" << sock->getAddr().port << "）断开连接" << std::endl;

					auto it = std::remove_if(clientSockets.begin(), clientSockets.end(), [sock](const std::unique_ptr<Socket> &ptr) { return ptr.get() == sock; });
					if (it != clientSockets.end()) {
						clientSockets.erase(it);
					}
				}
			}
		}
	}
}

// # 向8001端口发送数据
// echo "测试8001" | nc 127.0.0.1 8001
// # 向8002端口发送数据
// echo "测试8002" | nc 127.0.0.1 8002
int main() {
	testMultiPortServer();
	return 0;
}